home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 2.toast / pc / sample code / networking / pgpuam / sources / asipchallenge.cp next >
Encoding:
Text File  |  2000-06-23  |  6.7 KB  |  213 lines

  1. //    ASIPChallenge.cp - base class for Appleshare IP Challenge Object
  2. // 
  3. // Apple Macintosh Developer Technical Support
  4. // Written by:  Vinnie Moscaritolo
  5. //
  6. //  Copyright (work in progress)  Apple Computer, Inc All rights reserved.
  7. //
  8. // You may incorporate this sample code into your applications without
  9. // restriction, though the sample code has been provided "AS IS" and the
  10. // responsibility for its operation is 100% yours.  However, what you are
  11. // not permitted to do is to redistribute the source as "DSC Sample Code"
  12. // after having made changes. If you're going to re-distribute the source,
  13. // we require that you make it clear in the source that the code was
  14. // descended from Apple Sample Code, but that you've made changes.
  15. // 
  16.  
  17.  
  18. #include <string.h>
  19. #include <TextUtils.h>
  20. #include <PLStringFuncs.h>
  21.  
  22. #include "ASIPChallenge.h"
  23. #include "PassphraseCache.h"
  24. #include "TPGPException.h"
  25.  
  26. #include "pgpRandomPool.h"
  27. #include "pgpUserInterface.h"
  28.  
  29.  
  30. // ---------------------------------------------------------------------------
  31. void  MakeChallenge(TPGPkey *theKey, StringPtr outBuf)
  32. // ---------------------------------------------------------------------------
  33. //   
  34. //    outBuf        --> [len][challenge]  
  35. {
  36.  
  37.     PGPSize challengeSize;
  38.     PGPError err;
  39.         
  40.     challengeSize = theKey->GetHashSize();
  41.  
  42.     while ((err = PGPContextGetRandomBytes(TPGPkey::fgContext, &outBuf[1], challengeSize)) == kPGPError_OutOfEntropy  )
  43.     {
  44. // handle entropy errors?
  45. // what about no UI?
  46.         ThrowIfPGPErr(
  47.             PGPCollectRandomDataDialog(TPGPkey::fgContext, 
  48.                 PGPGlobalRandomPoolGetMinimumEntropy() - PGPGlobalRandomPoolGetEntropy(), 
  49.                 PGPOLastOption(TPGPkey::fgContext )));
  50.     }
  51.     ThrowIfPGPErr(err);    
  52.  
  53.     outBuf[0] = challengeSize & 0xFF;
  54.  
  55. }
  56.  
  57.  
  58. #define counterChallengeSize  64
  59.  
  60. // ---------------------------------------------------------------------------
  61. void ReplyToChallenge(TPGPkey *serverKey, const char *passPhrase, TPGPkey *clientKey, StringPtr inBuf, StringPtr outBuf)
  62. // ---------------------------------------------------------------------------
  63. //   
  64. //    inBuf        --> [len][challenge]  
  65. //
  66. //      outBuf    <-- [len of total][offset to orig challenge][counterchallenge] [sig]
  67.         
  68. {
  69.  
  70.     UInt8    *counterChallenge = (UInt8*) outBuf + 1;
  71.      UInt8    offset;
  72.      PGPSize sigBufSize = 0;
  73.          
  74.     ThrowPGPErrIfTrue( clientKey->GetHashSize() * 2 > counterChallengeSize , kPGPError_BufferTooSmall);
  75.           
  76. // calculate counter challenge string
  77.      PGPContextGetRandomBytes(TPGPkey::fgContext, counterChallenge, counterChallengeSize );
  78.  
  79. // offset the challenge into the counterchallenge
  80.       offset =  counterChallengeSize - inBuf[0] - (counterChallenge[0] & 0x1F); 
  81.       ThrowPGPErrIfTrue ( offset < 1, kPGPError_BufferTooSmall);
  82.       counterChallenge[0] = offset;
  83.      memcpy(&counterChallenge[offset], inBuf+1, inBuf[0]);
  84.  
  85.  // sign  the counter challenge
  86.      if(serverKey && serverKey->CanSign() )
  87.          serverKey->Sign(counterChallenge, counterChallengeSize , counterChallenge + counterChallengeSize, &sigBufSize, passPhrase);
  88.          
  89.     outBuf[0] = (sigBufSize & 0xFF) + 64;
  90.     
  91.  
  92. }
  93.  
  94.  
  95. // ---------------------------------------------------------------------------
  96. Boolean VerifyChallenge(TPGPkey *theKey,StringPtr origChallenge, StringPtr inBuf)
  97. // ---------------------------------------------------------------------------
  98. //   
  99. //    origChallenge        <-- [len][challenge]  
  100. //      inBuf                <-- [len of total][offset to orig challenge][counterchallenge] [sig]
  101. //
  102. {
  103.     
  104.      // check if challenge string is correct.
  105.     if(!(memcmp(  &inBuf[ inBuf[1] + 1] , &origChallenge[1], origChallenge[0]) == 0 )) 
  106.         return false;
  107.     
  108.     // check sig
  109.     return theKey->Verify(    &inBuf[1], 64,     &inBuf[65], inBuf[0] - 64);
  110.   
  111. }
  112.  
  113. // ---------------------------------------------------------------------------
  114. PGPError ReplyToCounterChallenge(StringPtr promptString, StringPtr fpBuf, StringPtr inBuf, StringPtr outBuf)
  115. // ---------------------------------------------------------------------------
  116. //   
  117. //    fpBuf            <-- [len][fingerprint of challenged]  
  118. //      inBuf            <-- [len of total][offset to orig challenge][counterchallenge] [sig]
  119. //    outbuf        --> [len of sig] [sig]
  120. //
  121. //
  122. {
  123.     PGPFilterRef    theFilter         = kInvalidPGPFilterRef;
  124.     PGPKeyIterRef    theIterator     = kInvalidPGPKeyIterRef;
  125.     PGPKeyListRef    theKeyListRef     = kInvalidPGPKeyListRef;
  126.     PGPKeyRef        theKeyRef        = kInvalidPGPKeyRef;
  127.     PGPOptionListRef optionList        = kInvalidPGPOptionListRef;
  128.     PGPContextRef     context            = TPGPkey::fgContext;
  129.     PGPKeySetRef    newKeySet         = NULL;
  130.     PGPUInt32         numKeys;
  131.     PGPError         err             = noErr;            
  132.  
  133. // Find key in database
  134.       ThrowIfPGPErr( PGPNewKeyFingerPrintFilter(TPGPkey::fgContext,&fpBuf[1],fpBuf[0] , &theFilter));
  135.     ThrowIfPGPErr( PGPFilterKeySet(TPGPkey::fgPGPKeySetRef , theFilter, &newKeySet));
  136.     PGPFreeFilter(theFilter);
  137.      ThrowIfPGPErr( PGPCountKeys(newKeySet, &numKeys));
  138.  
  139.     if(numKeys != 1) 
  140.         err = kPGPError_KeyInvalid;
  141.     else
  142.     {    
  143.         unsigned char    promptStr[256];
  144.         char *thePassphrase    = NULL;
  145.  
  146.         ThrowIfPGPErr( PGPOrderKeySet(newKeySet,kPGPAnyOrdering, &theKeyListRef));
  147.         ThrowIfPGPErr( PGPNewKeyIter( theKeyListRef, &theIterator ));
  148.         ThrowIfPGPErr( PGPKeyIterNext( theIterator, &theKeyRef ));
  149.         
  150.         ThrowIfPGPErr ( PGPBuildOptionList( context, &optionList,
  151.                             PGPOUIOutputPassphrase(context, &thePassphrase),
  152.                             PGPOUIDefaultKey(context, theKeyRef),
  153.                             PGPOUIVerifyPassphrase(context, true),
  154.                             PGPOLastOption(context) ));
  155.  
  156.         if(promptString) 
  157.         {
  158.             ThrowIfPGPErr ( PGPAppendOptionList( optionList,
  159.                             PGPOUIDialogPrompt(context, (char *)promptString),
  160.                             PGPOLastOption(context) ));
  161.         };
  162.          
  163.         if( GetPassphrase(TPGPkey::fgContext, theKeyRef, &thePassphrase) 
  164.             || (  (err = PGPSigningPassphraseDialog(context, newKeySet, &theKeyRef,
  165.                             optionList,
  166.                             PGPOLastOption(TPGPkey::fgContext ))) ==  kPGPError_NoErr )
  167.             && (RememberPassphrase(theKeyRef, thePassphrase), true))
  168.         {
  169.             TPGPkey    theKey;
  170.             PGPSize sigBufSize;
  171.             
  172.             theKey.Initialize(theKeyRef);
  173.             
  174.             if( theKey.IsOperational())
  175.             {
  176.                  if( ! theKey.Sign(&inBuf[1], 64, &outBuf[1], &sigBufSize, thePassphrase))
  177.                      err = kPGPError_KeyInvalid;
  178.                  outBuf[0] = (sigBufSize & 0xFF);
  179.             }                        
  180.          
  181.              // Erase passphrase                                    
  182.             PGPFreeData(thePassphrase);
  183.             thePassphrase = NULL;
  184.         }
  185.         
  186.         if(err == kPGPError_UserAbort) err = userCanceledErr;
  187.      
  188.     }
  189.     PGPFreeOptionList(optionList);
  190.     PGPFreeKeyIter(theIterator );
  191.     PGPFreeKeyList(theKeyListRef );
  192.     PGPFreeKeySet(newKeySet );
  193.  
  194.     return err;
  195. }
  196.  
  197.  
  198. // ---------------------------------------------------------------------------
  199. Boolean VerifyCounterChallenge(TPGPkey *theKey, StringPtr origCounterChallenge, StringPtr inBuf)
  200. // ---------------------------------------------------------------------------
  201. //   
  202. //      origCounterChallenge    <-- [len of total][offset to orig challenge][counterchallenge] [sig]
  203. //    inBuf                    <-- [len of sig] [sig]
  204.  
  205. {
  206.  
  207.         return theKey->Verify(    &origCounterChallenge[1], 64,    &inBuf[1], inBuf[0]);
  208.  
  209. }
  210.  
  211.      
  212.     
  213.